package com.young.common.expression;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorBoolean;
import com.googlecode.aviator.runtime.type.AviatorObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.oro.text.regex.*;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description：
 * @author: yangyahui01
 * @date: 11/29/24 12:47 PM
 */
public class AviatorRegexMatcher implements Matcher<String> {
    private static final String SPLIT = ",";
    private static final String PATTERN_SPLIT = "|";
    private static final String FILTER_EXPRESSION = "regex(pattern,target)";
    private static final AviatorRegexMatcher.RegexFunction regexFunction = new AviatorRegexMatcher.RegexFunction();
    private final Expression exp;
    private static final Comparator<String> COMPARATOR;
    private final String pattern;
    private final boolean defaultEmptyValue;
    protected static final Map<String, Pattern> PATTERNS;

    public AviatorRegexMatcher(String pattern) {
        this(pattern, true);
    }

    public AviatorRegexMatcher(String pattern, boolean defaultEmptyValue) {
        this.exp = AviatorEvaluator.compile("regex(pattern,target)", true);
        this.defaultEmptyValue = defaultEmptyValue;
        List<String> list = new ArrayList();
        if (!StringUtils.isEmpty(pattern)) {
            String[] ss = StringUtils.split(pattern, ",");
            list.addAll(Arrays.asList(ss));
        }

        list.sort(COMPARATOR);
        List<String> listR = this.completionPattern(list);
        this.pattern = StringUtils.join(listR, "|");
    }

    public boolean match(String source) {
        if (StringUtils.isEmpty(this.pattern)) {
            return this.defaultEmptyValue;
        } else if (StringUtils.isEmpty(source)) {
            return this.defaultEmptyValue;
        } else {
            Map<String, Object> env = new HashMap();
            env.put("pattern", this.pattern);
            env.put("target", source.toLowerCase());
            return (Boolean)this.exp.execute(env);
        }
    }

    private List<String> completionPattern(List<String> patterns) {
        List<String> result = new ArrayList();
        Iterator var3 = patterns.iterator();

        while(var3.hasNext()) {
            String pattern = (String)var3.next();
            result.add("^" + pattern + "$");
        }

        return result;
    }

    protected static Pattern getPattern(String pattern) {
        if (PATTERNS.containsKey(pattern)) {
            return (Pattern)PATTERNS.get(pattern);
        } else {
            synchronized(PATTERNS) {
                if (PATTERNS.containsKey(pattern)) {
                    return (Pattern)PATTERNS.get(pattern);
                } else {
                    Pattern var10000;
                    try {
                        PatternCompiler pc = new Perl5Compiler();
                        Pattern p = pc.compile(pattern, 32785);
                        PATTERNS.putIfAbsent(pattern, p);
                        var10000 = p;
                    } catch (MalformedPatternException var5) {
                        throw new RuntimeException("compile pattern error,pattern:" + pattern, var5);
                    }

                    return var10000;
                }
            }
        }
    }

    public static void clear() {
        PATTERNS.clear();
    }

    public static void main(String[] args) {
        AviatorRegexMatcher filter = new AviatorRegexMatcher("test\\..*");
        System.out.println(filter.match("test"));
        System.out.println(filter.match("test.t1"));
        System.out.println(filter.match("OK"));
        filter = new AviatorRegexMatcher("test.t1,test.t2");
        System.out.println(filter.match("test.t1"));
        System.out.println(filter.match("test2.t1"));
        filter = new AviatorRegexMatcher(".*.vipkid.com");
        System.out.println(filter.match("test.vipkid.com"));
    }

    static {
        AviatorEvaluator.addFunction(regexFunction);
        COMPARATOR = new AviatorRegexMatcher.StringComparator();
        PATTERNS = new ConcurrentHashMap();
    }

    public static class RegexFunction extends AbstractFunction {
        public RegexFunction() {
        }

        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            String pattern = FunctionUtils.getStringValue(arg1, env);
            String text = FunctionUtils.getStringValue(arg2, env);
            Perl5Matcher matcher = new Perl5Matcher();
            boolean isMatch = matcher.matches(text, AviatorRegexMatcher.getPattern(pattern));
            return AviatorBoolean.valueOf(isMatch);
        }

        public String getName() {
            return "regex";
        }
    }

    private static class StringComparator implements Comparator<String> {
        private StringComparator() {
        }

        public int compare(String str1, String str2) {
            return Integer.compare(str2.length(), str1.length());
        }
    }
}

